package com.pandora.framework.util;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.pandora.common.check.ConfigChecks;
import com.pandora.common.exception.EduException;
import com.pandora.common.util.CollectionUtils;
import com.pandora.common.util.CommonUtils;
import com.pandora.common.util.StringUtils;
import com.pandora.framework.constant.Constants;
import com.pandora.framework.constant.ResponseConstants;
import com.pandora.framework.constant.ServiceConstants;
import com.pandora.framework.constant.ServletConstants;
import com.pandora.framework.vo.ServiceConfigVO;

/**
 * 接口服务工具
 * 
 * @author JingChenglong 2017/12/16 13:27
 *
 */
public class ServiceConfigUtils {

	/** 系统总接口配置文件文件名 */
	private static final String SERVLET_CONFIG_FILENAME = "servlet-config.xml";

	private static Map<String, ServiceConfigVO> serviceConfigMap = null;

	/** 初始化，加载本地接口配置文件 */
	@SuppressWarnings("unchecked")
	public static void init() {

		serviceConfigMap = new HashMap<String, ServiceConfigVO>();

		String path = ServletConstants.SERVLETCONTEXTREALPATH + "/WEB-INF/";

		Document doc = null;
		SAXReader saxReader = new SAXReader();
		try {
			doc = saxReader.read(new File(path + SERVLET_CONFIG_FILENAME));
		} catch (DocumentException e) {
			LogUtils.logError(CommonUtils.getTraceInfo() + e.getMessage());
			return;
		}

		if (doc == null) {
			return;
		}

		Element root = doc.getRootElement();

		if (root == null) {
			return;
		}

		List<Element> serviceConfigList = root.elements("include");

		if (CollectionUtils.isEmpty(serviceConfigList)) {
			return;
		}

		ServiceConfigVO vo = null;

		String subPath = "";
		for (Element element : serviceConfigList) {

			subPath = path + StringUtils.nullToStrTrim(element.attributeValue("file"));

			try {
				doc = saxReader.read(subPath);
			} catch (Exception e) {
				LogUtils.logError(CommonUtils.getTraceInfo() + e.getMessage());
				continue;
			}
			if (doc == null) {
				continue;
			}
			root = doc.getRootElement();
			if (root == null) {
				continue;
			}

			List<Element> subElementList = root.elements("group");

			if (CollectionUtils.isEmpty(subElementList)) {
				continue;
			}

			String type = "";// 接口组类型
			String groupIp = "";
			String groupStatus = "";
			String groupSignType = "";
			String groupTimeOut = "";
			String groupAccessIdFlag = "";
			String accessIdValue = "";
			String accessKeyValue = "";
			String groupServiceType = "";

			String ip = "";
			String action = "";
			String signType = "";
			String status = "";
			String timeOut = "";
			String accessIdFlag = "";
			String serviceType = "";

			for (Element subElement : subElementList) {
				type = StringUtils.nullToStrTrim(subElement.attributeValue("type")).toLowerCase();
				groupIp = StringUtils.nullToStrTrim(PropertiesUtils.getIpLimit(("ip_" + type)));
				groupStatus = StringUtils.nullToStrTrim(subElement.attributeValue("status")).toLowerCase();
				groupSignType = StringUtils.nullToStrTrim(subElement.attributeValue("signtype")).toLowerCase();
				groupAccessIdFlag = StringUtils.nullToStrTrim(subElement.attributeValue("accessidflag")).toLowerCase();
				accessIdValue = StringUtils.nullToStrTrim(subElement.attributeValue("accessidvalue")).toLowerCase();
				accessKeyValue = StringUtils.nullToStrTrim(subElement.attributeValue("accesskeyvalue")).toLowerCase();
				groupTimeOut = StringUtils.nullToStrTrim(subElement.attributeValue("timeout")).toLowerCase();
				groupServiceType = StringUtils.nullToStrTrim(subElement.attributeValue("servicetype")).toLowerCase();

				List<Element> serviceEleList = subElement.elements("service");
				for (Element serviceEle : serviceEleList) {
					status = groupStatus;

					vo = new ServiceConfigVO();
					vo.setStatus(status);
					vo.setType(type);
					vo.setAccessIdValue(accessIdValue);
					vo.setAccessKeyValue(accessKeyValue);

					ip = groupIp + Constants.PARAM_SEPARATOR
							+ StringUtils.nullToStrTrim(subElement.attributeValue("ip"));

					ip = StringUtils.subStartAndEndChar(ip, Constants.PARAM_SEPARATOR);

					vo.setIp(ip);

					if (!ServiceConstants.SERVICE_STATUS_STOP.equals(groupStatus)) {
						status = StringUtils.nullToStrTrim(serviceEle.attributeValue("status"));
					}
					if (StringUtils.isEmpty(status)) {
						status = ServiceConstants.SERVICE_STATUS_RUNNING;
					}
					vo.setStatus(status);

					timeOut = StringUtils.nullToStrTrim(serviceEle.attributeValue("timeout"));
					if (StringUtils.isEmpty(timeOut)) {
						timeOut = groupTimeOut;
					}
					vo.setTimeout(timeOut);

					serviceType = StringUtils.nullToStrTrim(serviceEle.attributeValue("serivicetype"));
					if (StringUtils.isEmpty(serviceType)) {
						serviceType = groupServiceType;
					}
					vo.setServiceType(serviceType);

					signType = StringUtils.nullToStrTrim(serviceEle.attributeValue("signtype")).toLowerCase();
					if (StringUtils.isEmpty(signType)) {
						signType = groupSignType;
					}
					vo.setSignType(signType);
					if (StringUtils.isEmpty(vo.getSignType())) {
						vo.setSignType(ServiceConstants.SERVICE_SIGNTYPE_MD5);
					}

					accessIdFlag = StringUtils.nullToStrTrim(serviceEle.attributeValue("accessidflag")).toLowerCase();
					if (StringUtils.isEmpty(accessIdFlag)) {
						accessIdFlag = groupAccessIdFlag;
					}
					vo.setAccessIdFlag(accessIdFlag);

					vo.setResFlag(StringUtils.nullToStrTrim(serviceEle.attributeValue("resflag")).toLowerCase());
					vo.setUpFlag(StringUtils.nullToStrTrim(serviceEle.attributeValue("upflag")).toLowerCase());
					if (ServiceConstants.UP_FLAG_TRUE.equals(vo.getUpFlag())) {
						vo.setMaxLength(StringUtils.nullToIntZero(serviceEle.attributeValue("maxlength")));
						vo.setUpNullFlag(
								StringUtils.nullToStrTrim(serviceEle.attributeValue("upnullflag")).toLowerCase());
					}

					Class<?> classObj = null;
					try {
						classObj = Class.forName(StringUtils.nullToStrTrim(serviceEle.attributeValue("class")));
					} catch (Exception e) {
						LogUtils.logError(CommonUtils.getTraceInfo() + e.getMessage());
						System.exit(0);
					}
					vo.setClassObject(classObj);

					action = StringUtils.nullToStrTrim(serviceEle.attributeValue("action")).trim();
					if (serviceConfigMap.containsKey(action.toLowerCase())) {
						LogUtils.printError("Action [" + action + "] already exist");
						System.exit(0);
					}

					serviceConfigMap.put(action, vo);
				}
			}
		}
	}

	public static void destory() {
		serviceConfigMap.clear();
		serviceConfigMap = null;
	}

	/**
	 * 根据action获取服务接口对象
	 * 
	 * @param action
	 * @return
	 */
	public static ServiceConfigVO getServiceConfig(String action) throws EduException {

		if (CollectionUtils.isEmpty(serviceConfigMap)) {
			LogUtils.logError(CommonUtils.getTraceInfo() + "serviceConfigMap=null");
			throw new EduException(ResponseConstants.SYSTEMBUSY);
		}

		action = StringUtils.nullToStrTrim(action).toLowerCase();
		ConfigChecks.checkAction(action);

		ServiceConfigVO vo = serviceConfigMap.get(action);

		if (vo == null) {
			throw new EduException(ResponseConstants.SERVICE_INTERFACE_NULL);
		}

		return vo;
	}
}